-- PROGRESS
-- Output buffer & filename
local tmp_ofile, ofilename
-- Process information
local produced_lines, process_time

-- Execution initialization function
function Init(input_filename, output_filename)
	if type(input_filename) ~= "string" or type(output_filename) ~= "string" then
		error("string and string expected", 2)
	end
	-- Prepare output
	if output_filename:len() > 0 then
		tmp_ofile = io.tmpfile()
		ofilename = output_filename
		produced_lines = 0
		process_time = os.clock()
	end
	-- Read input
	local content
	if input_filename:len() > 0 then
		local ifile = io.open(input_filename, "r")
		if ifile then
			content = ifile:read("*a")
			ifile:close()
		else
			error("couldn't read input file: " .. input_filename, 1)
		end
	else
		content =
[[[Script Info]
; Script generated by NyuFX 1.6
Title: Default NyuFX file
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 704
PlayResY: 396
ScaledBorderAndShadow: yes
Video Aspect Ratio: 0
Video Zoom: 8
Video Position: 0
Last style Storage: Default
Video File: ?dummy:23.976000:1439:704:396:27:0:255:

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, Borderstylee, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Arial,30,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,0,8,10,10,10,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.00,0:00:10.00,Default,,0000,0000,0000,,Test]]
	end
	-- Evaluate input
	if tmp_ofile then
		local template = content:gsub("\nDialogue:", "\nComment:"):gsub("\n+$", "")
		tmp_ofile:write(template)
	end
	io.load_ass(content)
end

-- Execution exit function
function Exit()
	-- Output buffer exists
	if tmp_ofile then
		-- Copy buffer to output file
		local ofile = io.open(ofilename, "w")
		if ofile then
			tmp_ofile:seek("set")
			for line in tmp_ofile:lines() do
				ofile:write(line)
				ofile:write("\n")
			end
			tmp_ofile:close()
			ofile:close()
			print( string.format("Produced lines: %d\nProcess duration (in seconds): %.3f", produced_lines, os.clock() - process_time) )
		else
			error("couldn't create output file: " .. ofilename, 1)
		end
	end
end

-- IO
function io.write_line(line)
	-- Check line
	if type(line) ~= "table" then
		error("table expected", 2)
	elseif type(line.comment) ~= "boolean" or
		type(line.layer) ~= "number" or
		type(line.start_time) ~= "number" or
		type(line.end_time) ~= "number" or
		line.style == nil or tostring(line.style) == nil or
		line.actor == nil or tostring(line.actor) == nil or
		type(line.margin_l) ~= "number" or
		type(line.margin_r) ~= "number" or
		type(line.margin_v) ~= "number" or
		line.effect == nil or tostring(line.effect) == nil or
		line.text == nil or tostring(line.text) == nil then
		error("valid table expected", 2)
	end
	-- Convert line
	local function timestamp(t)
		-- Hours
		local h = math.floor(t / 3600000)
		t = t % 3600000
		-- Minutes
		local m = math.floor(t / 60000)
		t = t % 60000
		-- Seconds
		local s = math.floor(t / 1000)
		t = t % 1000
		-- Milliseconds
		local ms = math.floor(t / 10)
		-- Timestamp
		return string.format("%d:%02d:%02d.%02d", h, m, s, ms)
	end
	local text = string.format("\n%s: %d,%s,%s,%s,%s,%04d,%04d,%04d,%s,%s",
								line.comment and "Comment" or "Dialogue",
								line.layer,
								timestamp(line.start_time),
								timestamp(line.end_time),
								tostring(line.style),
								tostring(line.actor),
								line.margin_l,
								line.margin_r,
								line.margin_v,
								tostring(line.effect),
								tostring(line.text)
							)
	-- Write line
	if tmp_ofile then
		tmp_ofile:write(text)
		produced_lines = produced_lines + 1
	end
end
